import asyncio
from datetime import datetime

from fastapi import APIRouter, Depends, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession

from config.enums import BusinessType
from config.get_db import get_db
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from module_kylin.entity.vo.future_daily_quote_vo import FutureDailyQuotePageQueryModel, FutureDailyQuoteModel, \
    DeleteFutureDailyQuoteModel
from module_kylin.service.future_daily_quote_service import FutureDailyQuoteService
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil

futureDailyQuoteController = APIRouter(prefix='/kylin/futureDailyQuote',
                                       dependencies=[Depends(LoginService.get_current_user)])


@futureDailyQuoteController.get('/list', response_model=PageResponseModel,
                                dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:list'))])
async def get_kylin_future_daily_quote_list(
        request: Request,
        future_daily_quote_page_query: FutureDailyQuotePageQueryModel = Depends(
            FutureDailyQuotePageQueryModel.as_query),
        query_db: AsyncSession = Depends(get_db),
):
    # 获取分页数据
    future_daily_quote_page_query_result = await FutureDailyQuoteService.get_quote_list_services(query_db,
                                                                                                 future_daily_quote_page_query,
                                                                                                 is_page=True)
    logger.info('获取期货日线行情列表成功')
    return ResponseUtil.success(model_content=future_daily_quote_page_query_result)


@futureDailyQuoteController.get('/{id}', response_model=FutureDailyQuoteModel,
                                dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:query'))])
async def query_detail_kylin_future_daily_quote(request: Request, id: int, query_db: AsyncSession = Depends(get_db)):
    future_daily_quote_detail_result = await FutureDailyQuoteService.quote_detail_services(query_db, id)
    logger.info(f'获取id为{id}的期货日线行情信息成功')

    return ResponseUtil.success(data=future_daily_quote_detail_result)


@futureDailyQuoteController.post('', dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:add'))])
@ValidateFields(validate_model='add_quote')
@Log(title='期货日线行情', business_type=BusinessType.INSERT)
async def add_kylin_future_daily_quote(
        request: Request,
        add_quote: FutureDailyQuoteModel,
        query_db: AsyncSession = Depends(get_db),
        current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
    add_quote_result = await FutureDailyQuoteService.add_quote_services(query_db, add_quote)
    logger.info(add_quote_result.message)
    return ResponseUtil.success(msg=add_quote_result.message)


@futureDailyQuoteController.put('', dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:edit'))])
@ValidateFields(validate_model='edit_quote')
@Log(title='期货日线行情', business_type=BusinessType.UPDATE)
async def edit_kylin_future_daily_quote(
        request: Request,
        edit_quote: FutureDailyQuoteModel,
        query_db: AsyncSession = Depends(get_db),
):
    edit_quote_result = await FutureDailyQuoteService.edit_quote_services(query_db, edit_quote)
    logger.info(edit_quote_result.message)

    return ResponseUtil.success(msg=edit_quote_result.message)


@futureDailyQuoteController.delete('/{quote_ids}',
                                   dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:remove'))])
@Log(title='期货日线行情', business_type=BusinessType.DELETE)
async def delete_kylin_future_daily_quote(request: Request, quote_ids: str, query_db: AsyncSession = Depends(get_db)):
    delete_quote = DeleteFutureDailyQuoteModel(quoteIds=quote_ids)
    delete_quote_result = await FutureDailyQuoteService.delete_quote_services(request, query_db, delete_quote)
    logger.info(delete_quote_result.message)

    return ResponseUtil.success(msg=delete_quote_result.message)


@futureDailyQuoteController.get('/fetch/{symbol}',
                                dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:fetch'))])
@Log(title='期货日线行情', business_type=BusinessType.IMPORT)
async def fetch_kylin_future_daily_quote(request: Request, symbol: str, query_db: AsyncSession = Depends(get_db)):
    """
    从外部数据源获取期货日线行情数据并保存到数据库
    
    :param request: 请求对象
    :param symbol: 期货代码
    :param query_db: 数据库会话对象
    :return: 操作结果
    """
    try:
        # 调用service层的方法处理业务逻辑
        result = await FutureDailyQuoteService.fetch_quote_services(query_db, symbol)
        return ResponseUtil.success(msg=result['message'])

    except Exception as e:
        logger.error(f'获取期货代码{symbol}的日线行情数据时发生错误: {str(e)}')
        return ResponseUtil.error(msg=f'获取期货行情数据失败: {str(e)}')


@futureDailyQuoteController.get('/weightedAverageClosePrice/{code}/{days}',
                                dependencies=[Depends(CheckUserInterfaceAuth('kylin:futureDailyQuote:query'))])
@Log(title='期货日线行情', business_type=BusinessType.OTHER)
async def get_weighted_avg_price(
        request: Request,
        code: str,
        days: int,
        query_db: AsyncSession = Depends(get_db)
):
    """
    计算特定期货代码和天数的收盘价格加权平均价格
    计算规则：sum（收盘价*成交量）/sum（成交量）
    
    :param request: 请求对象
    :param code: 期货代码
    :param days: 计算天数
    :param query_db: 数据库会话对象
    :return: 加权平均价格结果
    """
    try:
        # 调用service层的方法处理业务逻辑
        result = await FutureDailyQuoteService.get_weighted_average_close_price_services(query_db, code, days)
        
        if result['success']:
            logger.info(f'计算期货代码{code}最近{days}天的加权平均价格成功')
            return ResponseUtil.success(data=result['data'], msg=result['message'])
        else:
            logger.warning(f'计算期货代码{code}最近{days}天的加权平均价格失败: {result["message"]}')
            return ResponseUtil.error(msg=result['message'])
    except Exception as e:
        logger.error(f'计算期货代码{code}最近{days}天的加权平均价格时发生错误: {str(e)}')
        return ResponseUtil.error(msg=f'计算失败: {str(e)}')
